// resolve 用来拼接绝对路径的方法
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 提取css为单独文件，而并非打包到html中去
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// 压缩css的插件
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');

// html-webpack-plugin
// new HtmlWebpackPlugin()   功能：默认会创建一个空的html文件，不会自动引入打包输出的所有资源（js/css）
const htmlWebpackPlugin = new HtmlWebpackPlugin({
    // 复制 './src/index.html' 文件，并自动引入打包输出的所有资源（js/css）
    template: './src/index.html',
    // 重命名
    filename: 'index.html',
    minify: {
        // 移除空格
        collapseWhitespace: true,
        // 移除注释
        removeComments: true,
    }
});
const miniCssExtractPlugin = new MiniCssExtractPlugin({
    // 对输出的css文件进行重命名
    filename: 'css/built.css'
});
const optimizeCssAssetsPlugin = new OptimizeCssAssetsPlugin();

// 处理css和less都需要的loader处理器
const commonCssLoader = [
    MiniCssExtractPlugin.loader,  // 这个loader取代 style-loader .作用：提取js中的css成单独文件
    'css-laoder', // 将css文件变成 commonjs 模块加载到js中，里面内容是样式字符串
    {
        // 还需要在 package.json 中定义 browserslist
        loader: 'postcss-loader',
        options: {
            ident: 'postcss',
            plugins: () => [require('postcss-preset-env')]
        }
    }
]

// 对 node 环境的配置
// process.env.NODE_ENV = 'development';
// webpack 配置
const webPackConfig = {

    // 入口起点
    entry: './src/js/index.js',
    output: {
        // 输出文件名
        filename: 'js/build.js',
        // __dirname 是nodejs的变量，代表当前文件的目录的绝对路径,相当于【./】
        // resolve(__dirname,'build') 方法就相当于将这两个目录拼接起来
        path: resolve(__dirname, 'build')
    },
    module: {
        rules: [
            // css 处理
            {
                test: /\.css$/,
                use: [...commonCssLoader]
            },
            // less 处理
            {
                test: /\.less$/,
                use: [...commonCssLoader, 'less-loader']
            },
            // js eslint
            {
                test: /\.js$/,
                exclude: /node_modules/,
                // 正常来讲，一个文件只能被一个loader处理。
                // 当一个文件要被多个loader处理时，那么一定要指定loader执行的先后顺序： enforce: 'pre' 【优先执行】
                enforce: 'pre',
                loader: 'eslint-loader',
                options: {
                    // 自动修改eslint的相关格式
                    fix: true
                }
            },
            // js 按需解决兼容问题
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                options: {
                    presets: [
                        [
                            '@babel/preset-env',
                            {
                                // 按需加载
                                useBuiltIns: 'usage',
                                // 指定 core-js 版本
                                corejs: {
                                    version: 3
                                },
                                // 指定具体的兼容到那个版本的浏览器
                                targets: {
                                    chrome: '60',
                                    firefox: '60',
                                    ie: '9',
                                    safari: '10',
                                    edge: '17',
                                }
                            }
                        ]
                    ]
                }
            },
            // 图片处理
            {
                // test: /\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2/,
                test: /\.jpg|png|gif/,
                // 注：【当loader只有一个时可以使用方式二的模式写，如果有多个并且有不同的参数可以使用方式一】
                // 方式一配置
                // use: ['url-loader?limit=8192&esModule=false&name=[hash:10].[ext]']
                // 方式二配置
                loader: 'url-loader',
                options: {
                    // 图片大小小于8kb，就会被base64处理
                    // 优点：减少请求数量【减轻服务器压力】
                    // 缺点：图片体积会更大【文件请求速度更慢】
                    limit: 8 * 1024,
                    // 问题：因为url-loader默认使用es6模块化解析，而html-loader引入图片是commonjs
                    // img 标签进行解析时就会出现 src="[object Module]"
                    // 解决方案：关闭 url-loader 的es6模块化,使用commonjs来进行解析
                    esModule: false,
                    // 给图片进行重命名
                    // [hash:10] 取图片的hash值的前10位
                    // [ext] 取文件原来扩展名
                    name: '[hash:10].[ext]',
                    // 将图片输出到该文件夹下面
                    outputPath: 'imgs'
                }
            },
            // html 处理
            {
                test: /\.html$/,
                loader: 'html-loader' // 处理html文件中的img图片，【负责引入img,从而能被url-loader进行处理】
            },
            // 处理其他文件
            {
                exclude: /\.(js|css|less|html|jpg|png|gif)/,
                loader: 'file-loader',
                options: {
                    // 将其它文件输出到该文件夹下面
                    outputPath: 'media'
                }
            }
        ]
    },
    plugins: [
        htmlWebpackPlugin, miniCssExtractPlugin, optimizeCssAssetsPlugin
    ],
    // mode: 'development', // 开发模式
    mode: 'production', // 生产模式  会自动压缩js代码

    // 开发服务器 devServer ： 用来自动化【自动编译，自动打开浏览器，自动刷新】
    // 只会在内存中编译打包，不会有任何输出
    // 启动devServer指令： npx webpack-dev-server 
    devServer: {
        contentBase: resolve(__dirname, 'build'),
        // 启动gzip压缩
        compress: true,
        // 端口号
        port: 3000,
        // 是否自动打开默认浏览器
        open: false
    },

}

module.exports = webPackConfig

// npm i postcss-loader